# In an attempt to refactor the permission handling and fetching of models in most controller actions
# this abstract resource controller should be used as the superclass for all controllers that
# are managing a model with basic CRUD operations. The controller should have the plural name of the model.
class ResourceController < ApplicationController
  
  before_filter :find_or_initialize, :only => [:show, :new, :create, :edit, :update, :destroy]
  before_filter :update_attributes, :only => [:new, :create, :edit, :update]
  before_filter :authorize
  
  protected
    
    def find_or_initialize
      if params[:id].nil?
        instance_variable_set "@#{model_name}", model_class.new
      else
        instance_variable_set "@#{model_name}", model_class.find(params[:id])
      end
    end
  
    def update_attributes
      current_model.attributes = params[model_name]
      update_extra_attributes
    end
    
    def update_extra_attributes
      # hook for subclass
      # set extra attributes here if it needs to be set before authorization
    end
    
    def authorize
      unless authorized?
        flash[:error] = 'You are not authorized to complete that action'
        redirect_to logged_in? ? home_path : new_session_path
        false # return false so action isn't called
      end
    end
  
    def authorized?
      permission_actions.all? do |action|
        current_user.can?(action, model_name, current_model)
      end
    end
  
    def permission_actions
      case params[:action].to_sym
        when :index, :show  then [:view]
        when :new, :create  then [:view, :create]
        when :edit, :update then [:view, :update]
        when :destroy       then [:view, :destroy]
        else []
      end
    end
  
    def model_name
      params[:controller].singularize
    end
  
    def model_class
      model_name.camelize.constantize
    end
  
    def current_model
      instance_variable_get "@#{model_name}"
    end
  
end
